﻿Module Twitter
    Public Class PhotoPoster

        Private _password As String
        Private _username As String

        Public Property Password() As String
            Get
                Return _password
            End Get
            Set(ByVal value As String)
                _password = value
            End Set
        End Property

        Public Property Username() As String
            Get
                Return _username
            End Get
            Set(ByVal value As String)
                _username = value
            End Set
        End Property

        ''' <summary>
        ''' URL for the TwitPic API's upload method
        ''' </summary>
        Private Const TWITPIC_UPLADO_API_URL As String = "http://twitpic.com/api/upload"

        ''' <summary>
        ''' URL for the TwitPic API's upload and post method
        ''' </summary>
        Private Const TWITPIC_UPLOAD_AND_POST_API_URL As String = "http://twitpic.com/api/uploadAndPost"

        ''' <summary>
        ''' Uploads the photo and sends a new Tweet
        ''' </summary>
        ''' <param name="imageFile">The binary image data.</param>
        ''' <param name="tweetMessage">The tweet message.</param>
        ''' <returns>Return true, if the operation was succeded.</returns>
        Public Function UploadPhoto(ByVal imageFile As String, ByVal tweetMessage As String) As Boolean
            ' Documentation: http://www.twitpic.com/api.do

            Dim oFile As System.IO.FileInfo
            oFile = New System.IO.FileInfo(imageFile)

            Dim oFileStream As System.IO.FileStream = oFile.OpenRead()
            Dim lBytes As Long = oFileStream.Length
            Dim _fileData(lBytes - 1) As Byte
            If (lBytes > 0) Then
                ' Read the file into a byte array
                oFileStream.Read(_fileData, 0, lBytes)
                oFileStream.Close()
            End If

            Dim binaryImageData As Byte() = _fileData

            Dim fi As New IO.FileInfo(imageFile)

            Dim boundary As String = Guid.NewGuid().ToString()
            Dim requestUrl As String = If([String].IsNullOrEmpty(tweetMessage), TWITPIC_UPLADO_API_URL, TWITPIC_UPLOAD_AND_POST_API_URL)
            Dim request As System.Net.HttpWebRequest = DirectCast(System.Net.WebRequest.Create(requestUrl), System.Net.HttpWebRequest)
            Dim encoding__1 As String = "iso-8859-1"

            request.PreAuthenticate = True
            request.AllowWriteStreamBuffering = True
            request.ContentType = String.Format("multipart/form-data; boundary={0}", boundary)
            request.Method = "POST"

            Dim header As String = String.Format("--{0}", boundary)
            Dim footer As String = String.Format("--{0}--", boundary)

            Dim contents As New System.Text.StringBuilder()
            contents.AppendLine(header)

            'Dim fileContentType As String = GetImageContentType(filename)
            Dim fileHeader As String = [String].Format("Content-Disposition: file; name=""{0}""; filename=""{1}""", "media", imageFile)
            Dim fileData As String = System.Text.Encoding.GetEncoding(encoding__1).GetString(binaryImageData)

            contents.AppendLine(fileHeader)

            Dim mime As String = "/"
            Select Case fi.Extension
                Case ".jpg"
                    mime = "image/jpg"
                Case ".png"
                    mime = "image/png"
                Case ".bmp"
                    mime = "image/bmp"
                Case ".gif"
                    mime = "image/gif"
            End Select

            contents.AppendLine([String].Format("Content-Type: {0}", mime))
            contents.AppendLine()
            contents.AppendLine(fileData)

            contents.AppendLine(header)
            contents.AppendLine([String].Format("Content-Disposition: form-data; name=""{0}""", "username"))
            contents.AppendLine()
            contents.AppendLine(Me.Username)

            contents.AppendLine(header)
            contents.AppendLine([String].Format("Content-Disposition: form-data; name=""{0}""", "password"))
            contents.AppendLine()
            contents.AppendLine(Me.Password())

            If Not [String].IsNullOrEmpty(tweetMessage) Then
                contents.AppendLine(header)
                contents.AppendLine([String].Format("Content-Disposition: form-data; name=""{0}""", "message"))
                contents.AppendLine()
                contents.AppendLine(tweetMessage & "(Stardust)")
            End If

            contents.AppendLine(footer)

            Dim bytes As Byte() = System.Text.Encoding.GetEncoding(encoding__1).GetBytes(contents.ToString())
            request.ContentLength = bytes.Length

            Using requestStream As IO.Stream = request.GetRequestStream()
                requestStream.Write(bytes, 0, bytes.Length)

                Using response As System.Net.HttpWebResponse = DirectCast(request.GetResponse(), System.Net.HttpWebResponse)
                    Using reader As New IO.StreamReader(response.GetResponseStream())
                        Dim result As String = reader.ReadToEnd()

                        Dim doc As XDocument = XDocument.Parse(result)

                        Dim rsp As XElement = doc.Element("rsp")
                        Dim status As String = If(rsp.Attribute(XName.[Get]("status")) IsNot Nothing, rsp.Attribute(XName.[Get]("status")).Value, rsp.Attribute(XName.[Get]("stat")).Value)

                        Return status.ToUpperInvariant().Equals("OK")
                    End Using
                End Using
            End Using
        End Function

    End Class
End Module
